home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
pt20pc.zip
/
FOLLOW.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-04
|
7KB
|
260 lines
#include "pt.h"
#include "conio.h"
/* return 1 only if you see both buttons simultaneously down */
int pascal
/* XTAG:followSelection */
followSelection(w, lastRow, lastCol, evHead, oneTime)
struct window *w;
int lastRow, lastCol, evHead, oneTime;
{
extern unsigned char msgBuffer[];
extern long selBegin, selEnd;
extern int selMode;
extern union REGS rin, rout;
extern int scrRows, scrCols;
extern struct event events[];
extern unsigned char scrMapReset;
extern int mousePresent;
extern int autoScrollRate;
extern int debug;
extern int videoMode;
int col1, col2, l, m, n, r, fileId, ret;
int oldRow1, oldRow2, newRow1, newRow2;
int selRow1, selRow2, redoRow1, redoRow2;
int anchRow1, anchRow2, curRow, curCol;
int startButtons;
long cpNew, cpNew1, cpNew2, cp1;
long anchBegin, anchEnd, oldCp1, anchCp1;
long selCp1;
/* get the present mouse button state */
if( mousePresent ) {
rin.x.ax = 3;
int86(51, &rin, &rout);
startButtons = rout.x.bx;
} else
startButtons = 0x7;
/* anchor the selection at the current selection */
anchBegin = selBegin;
anchEnd = selEnd;
fileId = w->fileId;
col1 = w->col1 + 1;
col2 = w->col2 - 1;
ret = 0;
restartFollowing:
/* what rows is the selection on now? */
if( selBegin <= w->posTopline ) {
anchCp1 = w->posTopline;
anchRow1 = w->row1 + 1;
} else {
n = -1;
anchCp1 = prevLine(fileId, selBegin, &n);
posToxy(w, selBegin, &anchRow1, &r);
}
oldRow1 = anchRow1;
oldCp1 = anchCp1;
posToxy(w, selEnd, &anchRow2, &r);
oldRow2 = anchRow2;
if( oneTime ) {
curRow = lastRow;
curCol = lastCol;
goto firstTime;
}
/* This is the loop that follows the cursor selection */
while( 1 ) {
/* first find out the current cursor position and */
/* see if it has moved since we last checked */
/* wait for a mouse event */
while( !isMouseEvent(0) ) {
/* This is a BIOS call that does not have any */
/* direct purpose. It seems to be necessary so */
/* that things will not freeze up after a Ctrl-C */
/* is handled. I'm not sure why. */
getCPos(&l, &m);
}
evHead = getMouseEvent();
/* skip intermediate mouse movements if other mouse events */
/* are already on the queue */
while( 1 ) {
if( events[evHead].mask != 0x1 )
break;
if( !isMouseEvent(0) )
break;
evHead = getMouseEvent();
}
curRow = events[evHead].vertical>>3;
curCol = events[evHead].horizontal>>3;
/* normalize extension outside the window */
if( curRow <= w->row1 ) {
curRow = w->row1 + 1;
while( 1 ) {
/* set up the screen map and scroll window */
scrMapReset = 0;
setMap(w->row1, w->col1, w->row2, w->col2,
1, w->textColor);
maskTop(w);
downScroll(w, autoScrollRate);
/* change the selection */
l = w->row1 + 1;
m = w->col1 + 1;
xyToPos(&l, &m, &n, &cp1,
(struct window **)&r);
if( selBegin > cp1 )
selBegin = cp1;
redrawBox(0, 0, scrRows-1, scrCols-1);
scrMapReset = 1;
setMap(w->row1, w->col1, w->row2, w->col2,
1, w->textColor);
oldRow1 = w->row1 + 1;
oldCp1 = w->posTopline;
oldRow2 = w->row2 - 1;
if( isMouseEvent(0) ) {
evHead = getMouseEvent();
goto restartFollowing;
}
}
} else if( curRow >= w->row2 ) {
curRow = w->row2 - 1;
while( 1 ) {
/* set up the screen map and scroll window */
scrMapReset = 0;
setMap(w->row1, w->col1, w->row2, w->col2,
1, w->textColor);
maskTop(w);
upScroll(w, autoScrollRate);
/* change the selection */
l = w->row2 - 1;
m = w->col2 - 1;
xyToPos(&l, &m, &n, &cp1,
(struct window **)&r);
if( selEnd < cp1 )
selEnd = cp1;
redrawBox(0, 0, scrRows-1, scrCols-1);
scrMapReset = 1;
setMap(w->row1, w->col1, w->row2, w->col2,
1, w->textColor);
oldRow1 = w->row1 + 1;
oldCp1 = w->posTopline;
oldRow2 = w->row2 - 1;
if( isMouseEvent(0) ) {
evHead = getMouseEvent();
goto restartFollowing;
}
}
} else if( curCol <= w->col1 ) {
curCol = w->col1 + 1;
} else if( curCol >= w->col2 ) {
curCol = w->col2 - 1;
}
if( curRow != lastRow || curCol != lastCol ) {
firstTime:
/* The cursor has moved, so update the selection */
/* get the file position of the cursor position */
cpNew = xyToWindow(w, &curRow, &curCol);
/* Extend it according the the selection mode */
modeExtend(w, cpNew, &cpNew1, &cpNew2);
if( cpNew1 < anchBegin ) {
selBegin = cpNew1;
newRow1 = curRow;
n = -1;
cp1 = prevLine(fileId, cpNew1, &n);
} else {
selBegin = anchBegin;
newRow1 = anchRow1;
cp1 = anchCp1;
}
if( cpNew2 > anchEnd ) {
selEnd = cpNew2;
newRow2 = curRow;
} else {
selEnd = anchEnd;
newRow2 = anchRow2;
}
/* remember the rows of the current selection */
selRow1 = newRow1;
selCp1 = cp1;
selRow2 = newRow2;
/* what rows do we need to redraw? */
/* we need to erase the old selection as well as */
/* draw the new selection */
if( oldRow1 < newRow1 ) {
newRow1 = oldRow1;
cp1 = oldCp1;
} else
oldCp1 = cp1;
if( oldRow2 > newRow2 )
newRow2 = oldRow2;
/* try to reduce the screen redrawing by figuring */
/* out which rows have actually changed */
/* do not optimize for movement above the anchor row */
if( selRow1 == oldRow1 && selRow1 >= anchRow1) {
if( selRow2 >= oldRow2 ) {
redoRow1 = oldRow2;
redoRow2 = selRow2;
} else {
redoRow1 = selRow2;
redoRow2 = oldRow2;
}
} else {
redoRow1 = newRow1;
redoRow2 = newRow2;
}
/* update the changed rows in the screen buffer */
for(r = newRow1; r <= redoRow2; r++) {
if( redoRow1 <= r ) {
cp1 = fillLine(w, cp1, r, col1, col2);
} else {
n = 1;
cp1 = nextLine(fileId, cp1, &n);
}
if( cp1 == -1 ) /* EOF? */
break;
}
if( oneTime ) {
oneTime = 0;
updateScreen(0, scrRows-1);
} else {
updateScreen(redoRow1, redoRow2);
}
/* remember some things for the next iteration */
oldRow1 = selRow1;
oldCp1 = selCp1;
oldRow2 = selRow2;
lastRow = curRow;
lastCol = curCol;
}
/* are the buttons up now? */
if( events[evHead].buttons == 0 )
break;
/* check for both buttons down */
if( ((~startButtons) & events[evHead].buttons) != 0 ) {
ret = 1;
break;
}
}
/* selecting the end of line should include both CR and LF */
if( readChar(fileId, selBegin) == '\n' ) {
if( readChar(fileId, --selBegin) != '\r' )
++selBegin;
}
return ret;
}